Android 學習旅程總整理——從 Kotlin 基礎到 App 實作
不知不覺,Android 30 天學習挑戰來到最後一天。從一開始認識 Kotlin 語法、安裝 Android Studio,到後來實作 Activity、Fragment、RecyclerView、SQLite、Firebase 等功能,這 30 天不只是完成一系列文章,更是重新整理 Android App 開發知識的一段旅程。
Android Developers:https://developer.android.com/
剛開始規劃這個系列時,我希望透過每天一個主題,把 Android 開發拆成可以逐步理解的小單元。
與其一次閱讀大量文件,不如每天完成一項功能,從實際撰寫程式碼、遇到錯誤到解決問題,慢慢建立完整的 Android 開發觀念。
Kotlin 官方文件:https://kotlinlang.org/docs/home.html
這個系列的學習方向包含:
Android 開發訓練課程:https://developer.android.com/courses
Android App 可以使用 Kotlin 或 Java 開發,而 Kotlin 已經成為 Android 官方推薦的主要開發語言。
Kotlin for Android:https://developer.android.com/kotlin
在前面的學習中,我們從最基本的語法開始,包括:
val 與 var
for 與 while 迴圈object
companion object
Kotlin 基礎語法:https://kotlinlang.org/docs/basic-syntax.html
例如,Kotlin 可以利用 Null Safety 減少常見的空值錯誤:
fun main() {
// name 可以存放 String,也可以是 null
val name: String? = null
// 使用 ?. 安全呼叫,避免發生 NullPointerException
println(name?.length)
// 使用 ?: Elvis 運算子提供預設值
val displayName = name ?: "Android 學習者"
println("Hello, $displayName")
}
Kotlin Null Safety:https://kotlinlang.org/docs/null-safety.html
學習 Kotlin 不只是為了記住語法,更重要的是理解物件導向、資料處理及程式架構,因為後面的 Activity、Fragment、RecyclerView 和 Firebase 都會大量使用這些觀念。
建立第一個 Android 專案後,可以看到一個 App 並不是只有 Kotlin 程式,而是由多種檔案共同組成。
Android 專案結構:https://developer.android.com/studio/projects
常見的專案內容包括:
app/
├── manifests/
│ └── AndroidManifest.xml
│
├── kotlin/
│ └── MainActivity.kt
│
└── res/
├── drawable/
├── layout/
├── mipmap/
└── values/
├── colors.xml
├── strings.xml
└── themes.xml
其中:
AndroidManifest.xml:宣告 Activity、權限及 App 基本資訊。MainActivity.kt:撰寫畫面的程式邏輯。res/layout:存放 XML 畫面配置。res/drawable:存放圖片、Shape 及背景資源。res/values:存放文字、顏色和主題設定。App 資源管理:https://developer.android.com/guide/topics/resources/providing-resources
這個階段讓我理解到,Android 開發不是單純「把畫面做出來」,而是需要同時處理介面、程式邏輯、資源及生命週期。
Activity 是 Android App 最基本的畫面元件之一。當使用者開啟、離開或回到畫面時,系統會呼叫不同的生命週期方法。
Activity 生命週期:https://developer.android.com/guide/components/activities/activity-lifecycle
常見的生命週期方法包括:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Activity 第一次建立時執行
println("MainActivity:onCreate")
}
override fun onStart() {
super.onStart()
// Activity 即將顯示在畫面上
println("MainActivity:onStart")
}
override fun onResume() {
super.onResume()
// Activity 已經可以與使用者互動
println("MainActivity:onResume")
}
override fun onPause() {
super.onPause()
// Activity 暫時失去焦點
println("MainActivity:onPause")
}
override fun onStop() {
super.onStop()
// Activity 已經不可見
println("MainActivity:onStop")
}
override fun onDestroy() {
super.onDestroy()
// Activity 即將被銷毀
println("MainActivity:onDestroy")
}
}
透過 Logcat 觀察生命週期,可以更清楚了解旋轉螢幕、切換 App、跳轉頁面及按下返回鍵時,Android 系統如何管理 Activity。
Logcat 使用說明:https://developer.android.com/studio/debug/logcat
當 App 有兩個以上的 Activity 時,可以使用 Intent 開啟另一個畫面,並透過 putExtra() 傳遞資料。
Intent 與 Intent Filter:https://developer.android.com/guide/components/intents-filters
val intent = Intent(this, DisplayActivity::class.java)
// 傳送城市名稱
intent.putExtra("CITY_NAME", "桃園市")
// 傳送人口數
intent.putExtra("POPULATION", 2300000)
startActivity(intent)
接收資料:
class DisplayActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 接收上一個 Activity 傳來的資料
val cityName = intent.getStringExtra("CITY_NAME")
// 沒有取得資料時,預設值設為 0
val population = intent.getIntExtra("POPULATION", 0)
println("城市:$cityName")
println("人口:$population")
}
}
後續也練習了 Activity Result API,讓第二個畫面完成操作後,可以把結果傳回第一個畫面。
Activity Result API:https://developer.android.com/training/basics/intents/result
這部分讓我理解,畫面之間不只是單純跳轉,也需要設計清楚的資料流向。
Fragment 可以把畫面拆成多個可重複使用的區塊,也能在同一個 Activity 中切換不同內容。
Fragment 官方指南:https://developer.android.com/guide/fragments
Fragment 基本架構如下:
class Fragment1 : Fragment(R.layout.fragment_1) {
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
// Fragment 的 View 建立完成後,在這裡設定元件事件
val textView = view.findViewById<TextView>(R.id.textView)
textView.text = "這是 Fragment 1"
}
}
切換 Fragment:
supportFragmentManager
.beginTransaction()
.replace(R.id.fragmentContainer, Fragment1())
.addToBackStack(null)
.commit()
Fragment 交易:https://developer.android.com/guide/fragments/transactions
學習 Fragment 後,可以更容易設計首頁、分頁、設定頁或導覽列等複合式畫面。
在 BMI 表單練習中,我們使用 TextInputLayout、TextInputEditText 和 ConstraintLayout 建立輸入介面。
Material Text Fields:https://m3.material.io/components/text-fields/overview
除了取得使用者輸入,也要檢查資料是否為空、是否為數字,以及輸入範圍是否合理。
private fun calculateBmi() {
// 取得身高及體重輸入內容
val heightText = binding.editHeight.text.toString().trim()
val weightText = binding.editWeight.text.toString().trim()
// 檢查是否未輸入身高
if (heightText.isEmpty()) {
binding.layoutHeight.error = "請輸入身高"
return
} else {
binding.layoutHeight.error = null
}
// 檢查是否未輸入體重
if (weightText.isEmpty()) {
binding.layoutWeight.error = "請輸入體重"
return
} else {
binding.layoutWeight.error = null
}
// 使用 toDoubleOrNull(),避免非數字內容造成程式閃退
val heightCm = heightText.toDoubleOrNull()
val weightKg = weightText.toDoubleOrNull()
if (heightCm == null || heightCm <= 0) {
binding.layoutHeight.error = "身高格式不正確"
return
}
if (weightKg == null || weightKg <= 0) {
binding.layoutWeight.error = "體重格式不正確"
return
}
// 將公分轉換成公尺
val heightM = heightCm / 100.0
// BMI = 體重(公斤)÷ 身高(公尺)的平方
val bmi = weightKg / (heightM * heightM)
// 顯示到小數點後一位
binding.textResult.text = "BMI:%.1f".format(bmi)
}
ViewBinding:https://developer.android.com/topic/libraries/view-binding
這個實作讓我了解到,使用者輸入永遠不能直接相信。完整的 App 必須先驗證資料,才能繼續執行運算或儲存。
RecyclerView 是 Android 中非常重要的清單元件,可以用來顯示城市、美食、訊息、商品或感測器資料。
RecyclerView 官方指南:https://developer.android.com/develop/ui/views/layout/recyclerview
RecyclerView 通常包含:
data class
資料類別範例:
data class City(
val name: String,
val description: String,
val imageResId: Int
)
RecyclerView 的核心概念是重複利用畫面元件,避免每筆資料都建立新的 View,讓大量資料捲動時仍能維持良好效能。
當 App 關閉後仍需要保留資料,就不能只把內容放在變數中。
SQLite API:https://developer.android.com/training/data-storage/sqlite
SQLite 可以在裝置本機建立資料表,完成:
也就是常見的 CRUD:
Create:新增
Read:查詢
Update:修改
Delete:刪除
SQLiteOpenHelper:https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper
透過 SQLite 練習,可以理解資料表、欄位、主鍵以及 SQL 指令如何與 Android 程式配合。若開發較完整的新專案,也可以進一步使用 Room,讓資料庫操作更安全、更容易維護。
Room 官方指南:https://developer.android.com/training/data-storage/room
本機資料庫只能保留在單一裝置上。如果希望多台裝置共同存取資料,就需要串接後端服務或雲端資料庫。
Firebase Android 入門:https://firebase.google.com/docs/android/setup
Firebase 提供多種功能,例如:
Cloud Firestore:https://firebase.google.com/docs/firestore
透過 Firebase 練習,可以讓 Android App 從單機程式進一步發展成具有會員、同步、雲端儲存及推播能力的完整應用程式。
這個系列不只學習一般 App 功能,也接觸 BLE 與 MQTT,讓 Android 手機可以與外部硬體裝置溝通。
Android BLE:https://developer.android.com/develop/connectivity/bluetooth/ble/ble-overview
BLE 開發流程通常包括:
BluetoothGatt:https://developer.android.com/reference/android/bluetooth/BluetoothGatt
MQTT 則適合讓 Android App、ESP32、伺服器和其他物聯網裝置透過 Broker 交換訊息。
MQTT 官方網站:https://mqtt.org/
一個簡單的 MQTT 訊息流程可以表示為:
ESP32
↓ Publish
MQTT Broker
↓ Subscribe
Android App
BLE 適合近距離直接控制裝置;MQTT 則適合透過網路進行遠端控制與即時資料傳輸。
這 30 天並不是所有程式碼第一次執行就會成功。
實作過程中曾遇到:
lateinit 尚未初始化Android Studio 偵錯:https://developer.android.com/studio/debug
但這些錯誤也是學習中最有價值的部分。因為每解決一次問題,就會更了解 Android 的運作方式。
完成 30 天挑戰後,我認為最重要的收穫不是記住多少 API,而是建立解決問題的方法。
遇到錯誤時,我現在會依照以下順序處理:
Android Developers 文件:https://developer.android.com/docs
這種除錯與拆解問題的能力,不只適用於 Android,也適用於 iOS、Web、後端及物聯網開發。
完成 30 天,只代表已經建立基礎,並不代表所有 Android 技術都學完了。
接下來還可以繼續深入:
Jetpack Compose:https://developer.android.com/compose
Android App Architecture:https://developer.android.com/topic/architecture
Kotlin Coroutines:https://developer.android.com/kotlin/coroutines
這些技術可以讓 App 架構更清楚、程式碼更容易維護,也更符合現代 Android 專案的開發方式。
如果回到 Day 1,我會告訴當時的自己:
不需要一次把所有東西都學會,只要今天比昨天多理解一個觀念、多完成一項功能,就已經是在前進。
寫程式一定會遇到錯誤。有時候一個小問題可能會卡上幾個小時,但當它終於成功執行時,那份成就感正是持續學習的動力。
Android 基礎品質指南:https://developer.android.com/docs/quality-guidelines/core-app-quality
完成這次挑戰後,我已經實際接觸並練習:
Material Design 3:https://m3.material.io/
這些內容單獨來看可能只是一個個小功能,但組合起來後,就能成為具有介面、資料儲存、網路連線及硬體控制能力的完整 App。
Android 30 天學習挑戰正式完成。
感謝一路閱讀這個系列,也感謝沒有因為錯誤、閃退和版本問題而放棄的自己。
30 天前,我們從第一行 Kotlin 程式碼開始;30 天後,已經能建立畫面、切換頁面、傳遞資料、儲存內容、連接 Firebase,甚至透過 BLE 和 MQTT 與物聯網裝置通訊。
這不是終點,而是一個新的起點。
接下來,我會把這 30 天學到的技術整合到 Android 專題中,從「跟著範例完成程式」進一步走向「自己分析需求、設計架構並完成一套 App」。
Google Play Console:https://play.google.com/console/about/
我是 Alex,Android 30 天學習挑戰,我們完成了!
Day 30,END。
Android Developers
https://developer.android.com/
Kotlin 官方文件
https://kotlinlang.org/docs/home.html
Android Kotlin
https://developer.android.com/kotlin
Activity 生命週期
https://developer.android.com/guide/components/activities/activity-lifecycle
Fragment 官方指南
https://developer.android.com/guide/fragments
RecyclerView 官方指南
https://developer.android.com/develop/ui/views/layout/recyclerview
SQLite 資料儲存
https://developer.android.com/training/data-storage/sqlite
Room 資料庫
https://developer.android.com/training/data-storage/room
Firebase Android
https://firebase.google.com/docs/android/setup
Android BLE
https://developer.android.com/develop/connectivity/bluetooth/ble/ble-overview
Jetpack Compose
https://developer.android.com/compose
Android App Architecture
https://developer.android.com/topic/architecture
Google Play Console
https://play.google.com/console/about/